// socketing.cpp : Defines the entry point for the console application.
//
#include <winsock2.h>
#include <stdio.h>

#include "../Logger/Logger.h"
#include "../CommunicationControl/Network_Adapters_Info.h"

int main(int argc, char* argv[])
{
	int					Ret;
	WSADATA             wsaData;
	SOCKET              ListeningSocket;
	SOCKET              NewConnection;
	SOCKADDR_IN         ServerAddr;
	sockaddr			ClientAddr;
	int                 Port = 5150;

	
	int lNumberOfInterfaces = stNetwork_Adapters_Info::getInstance().GetNumberOfAdapters();
	sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("The number of interfaces is: %ld",lNumberOfInterfaces);

	// Initialize Winsock version 2.2
	if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
	{
		// NOTE: Since Winsock failed to load we cannot use 
		// WSAGetLastError to determine the specific error for
		// why it failed. Instead we can rely on the return 
		// status of WSAStartup.
		sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("WSAStartup failed with error %d\n", Ret);
		return Ret;
	}

	// Create a new socket to listen for client connections.

	ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	// Set up a SOCKADDR_IN structure that will tell bind that we
	// want to listen for connections on all interfaces using port
	// 5150. Notice how we convert the Port variable from host byte
	// order to network byte order.

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(Port);    
	ServerAddr.sin_addr.S_un.S_un_b.s_b1 = 127;
	ServerAddr.sin_addr.S_un.S_un_b.s_b2 = 0;
	ServerAddr.sin_addr.S_un.S_un_b.s_b3 = 0;
	ServerAddr.sin_addr.S_un.S_un_b.s_b4 = 1;

	// Associate the address information with the socket using bind.

	Ret = bind(ListeningSocket, (SOCKADDR *)&ServerAddr, 
		sizeof(ServerAddr));
	if (0 != Ret)
	{
		sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("bind failed: %ld ",Ret);
		return -1;
	}

	// Listen for client connections. We used a backlog of 5, which
	// is normal for many applications.

	sLogMsgf<LogLevel<LOG_LEVEL_NORMAL>,LineType<LOG_TYPE_NOTIFICATION> >("Start listening");
	Ret = listen(ListeningSocket, 5); 

	if (0 != Ret)
	{
		sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("listen failed: %ld",Ret);
		return -1;
	}

	// Accept a new connection when one arrives.
	int ClientAddrLen = 0;
	NewConnection = accept(ListeningSocket,NULL,NULL);
	
	sLogMsgf<LogLevel<LOG_LEVEL_NORMAL>,LineType<LOG_TYPE_NOTIFICATION> >("Accepted new connection");
	if (INVALID_SOCKET == NewConnection)
	{
		sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("accept Failed! %ld",WSAGetLastError());
		return -1;
	}

	int size = 0;
	while (size != -1)
	{
		char	sBuf[256] =  {0};
		size = recvfrom(NewConnection,sBuf,sizeof(sBuf),NULL,&ClientAddr,&ClientAddrLen);
		sLogMsgf<LogLevel<LOG_LEVEL_NORMAL>,LineType<> >("Buffer Recieved size: %ld Msg: %s",size,sBuf);
	}
	// At this point you can do two things with these sockets. Wait
	// for more connections by calling accept again on ListeningSocket
	// and start sending or receiving data on NewConnection. We will
	// describe how to send and receive data later in the chapter.

	// When you are finished sending and receiving data on the
	// NewConnection socket and are finished accepting new connections
	// on ListeningSocket, you should close the sockets using the
	// closesocket API. We will describe socket closure later in the 
	// chapter.

	closesocket(NewConnection);
	closesocket(ListeningSocket);

	// When your application is finished handling the connections, 
	// call WSACleanup.

	if (WSACleanup() == SOCKET_ERROR)
	{
		sLogMsgf<LogLevel<LOG_LEVEL_HIGH>,LineType<LOG_TYPE_EXCEPTION> >("WSACleanup failed with error %d\n", WSAGetLastError());
		return -1;
	}

	return 0;
}

